package com.jz.digital.utils;

import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
import java.util.ArrayList;

/**
 * Copyright (c) 2019 深圳市爱都科技有限公司. All rights reserved.
 *
 * @Author: xyb
 * @CreateDate: 2020/11/23 10:58
 * @description 图片相关的工具类
 */
public class BitmapUtil {

    private static final String TAG = "BitmapUtil";

    public static Bitmap getBitmapFromView(View view) {
        /**
         * 这个方法如果view太长，则会导致获取为null
         * W/View: LinearLayout not displayed because it is too large to fit into a software layer (or drawing cache), needs 10780056 bytes, only 10108800 available
         */
        if (view == null) return null;
        Bitmap bitmap = null;
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        bitmap = view.getDrawingCache();
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            view.draw(canvas);
        }
        view.setDrawingCacheEnabled(false);
        view.destroyDrawingCache();
        return bitmap;
    }
    public static Bitmap getBitmapStepFromView(View view) {
        /**
         * 这个方法如果view太长，则会导致获取为null
         * W/View: LinearLayout not displayed because it is too large to fit into a software layer (or drawing cache), needs 10780056 bytes, only 10108800 available
         */
        if (view == null) return null;
        Bitmap bitmap = null;
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            view.draw(canvas);
        }
        view.setDrawingCacheEnabled(false);
        view.destroyDrawingCache();
        return bitmap;
    }
    /**
     * Bitmap 保存到sdcard
     *
     * @param b           bitmap 对象，
     * @param strFileName 文件路径
     */
    public static void saveBitmap(Bitmap b, String strFileName) {
        if (b == null || TextUtils.isEmpty(strFileName)) return;
        FileOutputStream fos = null;
        try {
            File file = new File(strFileName);
            if (file.exists() && file.isFile()) file.delete();
            file.createNewFile();
            fos = new FileOutputStream(strFileName);
            if (null != fos) {
                b.compress(Bitmap.CompressFormat.PNG, 90, fos);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    fos.flush();
                    fos = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 转换为圆角图片
     *
     * @param source
     * @param recoup 补偿
     * @return
     */
    public static Bitmap transform2CycleBitmap(Bitmap source, float recoup) {
        if (source == null) {
            return null;
        }
        int x = source.getWidth();
        int y = source.getHeight();
        float radius = x >= y ? x / 2f : y / 2f;
        Bitmap bitmap = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setAntiAlias(true);
        canvas.drawCircle(x / 2f, y / 2f, radius - recoup, paint);
        return bitmap;
    }

    /**
     * 组装地图截图和其他View截图，需要注意的是目前提供的方法限定为MapView与其他View在同一个ViewGroup下
     *
     * @param bitmap        地图截图回调返回的结果
     * @param viewContainer MapView和其他要截图的View所在的父容器ViewGroup
     * @param mapView       MapView控件
     * @param views         其他想要在截图中显示的控件
     */
    public static Bitmap getMapAndViewScreenShot(Bitmap bitmap, ViewGroup viewContainer,
                                                 View mapView, boolean isScreeH, View... views) {
        if (bitmap == null || viewContainer == null || mapView == null || views == null)
            return null;
        int width = viewContainer.getWidth();
//        int height = viewContainer.getHeight();
        int h = viewContainer.getHeight();
        if (isScreeH) {
            h = 0;
            for (int i = 0; i < viewContainer.getChildCount(); i++) {
                h += viewContainer.getChildAt(i).getHeight();
            }
        }

        final Bitmap screenBitmap = Bitmap.createBitmap(width, h, Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(screenBitmap);
        if (bitmap != null) {
            canvas.drawBitmap(bitmap, mapView.getLeft(), mapView.getTop(), null);
        }
        for (View view : views) {
            if (view.getVisibility() == View.VISIBLE) {
                view.setDrawingCacheEnabled(true);
                canvas.drawBitmap(view.getDrawingCache(), view.getLeft(), view.getTop(), null);
            }

        }

        return screenBitmap;
    }

    /**
     * 组装地图截图和其他View截图，需要注意的是目前提供的方法限定为MapView与其他View在同一个ViewGroup下
     *
     * @param bitmap        地图截图回调返回的结果
     * @param viewContainer MapView和其他要截图的View所在的父容器ViewGroup
     * @param mapView       MapView控件
     * @param views         其他想要在截图中显示的控件
     */
    public static Bitmap getMapAndViewScreenShot2(Bitmap bitmap, ViewGroup viewContainer,
                                                  View mapView, boolean isScreeH, View... views) {
        if (viewContainer == null || views == null)
            return null;

        int width = viewContainer.getWidth();
//        int height = viewContainer.getHeight();
        int h = viewContainer.getHeight();
        if (isScreeH) {
            h = 0;
            for (int i = 0; i < viewContainer.getChildCount(); i++) {
                h += viewContainer.getChildAt(i).getHeight();
            }
        }
        final Bitmap screenBitmap = Bitmap.createBitmap(width, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(screenBitmap);
        //绘制view的背景颜色
        //canvas.drawColor(0xFFFF0000);
        canvas.drawColor(0xFFF0F0F0);
        if (bitmap != null && mapView != null) {
            canvas.drawBitmap(bitmap, mapView.getLeft(), mapView.getTop(), null);
        }
        for (View view : views) {
            if (view.getVisibility() == View.VISIBLE) {
                //此方法截地图会溢出
//                view.setDrawingCacheEnabled(true);
//                canvas.drawBitmap(view.getDrawingCache(), view.getLeft(), view.getTop(), null);
                // 为黑色的问题增加画笔解决 Bitmap 合成图片时 PNG透明背景
                Paint vPaint = new Paint();
                vPaint.setStyle(Paint.Style.STROKE);   //空心
                //vPaint .setAlpha( 75 );
                canvas.drawBitmap(loadBitmapFromView(view), view.getLeft(), view.getTop(), null);
            }

        }
        return screenBitmap;
    }

    /**
     * 截屏
     *
     * @param view         view
     */
    public static Bitmap getLongBitmapFromLayout(View view,int color) {
        if (view == null)
            return null;
        int width = view.getWidth();
        int height = view.getHeight();
        final Bitmap screenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(screenBitmap);
        canvas.drawColor(color);
        canvas.drawBitmap(loadBitmapFromView(view,color), view.getLeft(), view.getTop(), null);
        return screenBitmap;
    }

    /**
     * bitmap写入到文件。
     * <p>该方法适用于写入小文件，因为这是一次性的</p>
     *
     * @param file  文件实例
     * @param image 写入图片
     * @param file  文件实例
     * @return file存在则删除，写入新的内容
     */
    public static void savePngBitmap(Bitmap image, File file, boolean isCompressBit) {
        if (file.exists()) {
            file.delete();
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            if (isCompressBit) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.PNG, 100, baos);
                if (baos.toByteArray().length > FileDialDefinedUtil.IMAGE_SIZE * 2) {//图片小于50，不进行压缩。
                    int options = 100;
                    while (baos.toByteArray().length / 1024 > FileDialDefinedUtil.IMAGE_SIZE) { //图片很大，质量最低压倒40%。
                        baos.reset();//重置baos即清空baos
                        image.compress(Bitmap.CompressFormat.PNG, options, baos);
                        options -= 10;
                    }
                }
                ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
                Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
                if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                    out.flush();
                    out.close();
                }
            } else {
                if (image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                    out.flush();
                    out.close();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 截取地图截屏
     *
     * @param mapView
     * @return
     */
    public static Bitmap getMapScreen(Bitmap bitmap, View mapView, ViewGroup viewContainer) {
        if (bitmap == null || viewContainer == null || mapView == null)
            return null;

        int width = viewContainer.getWidth();
//        int height = viewContainer.getHeight();
        int h = viewContainer.getHeight();

        final Bitmap screenBitmap = Bitmap.createBitmap(width, h, Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(screenBitmap);
        //绘制view的背景颜色
        //canvas.drawColor(0xFFFF0000);
        canvas.drawColor(0xFFF0F0F0);
        if (bitmap != null) {
            canvas.drawBitmap(bitmap, mapView.getLeft(), mapView.getTop(), null);
        }

        return screenBitmap;
    }

    public static Bitmap loadBitmapFromView(View v) {
        if (v == null||v.getVisibility()!=View.VISIBLE) return null;
        if (v.getWidth()==0&&v.getHeight()==0){
            v.requestLayout();
        }
        if (v.getWidth()+v.getHeight()==0)return null;
        int height = v.getHeight();
        int width = v.getWidth();
        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(b);
        v.draw(c);
        return b;
    }

    public static Bitmap loadBitmapFromView(View v,int color) {
        if (v == null) return null;
        int height = v.getHeight();
        int width = v.getWidth();
        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        c.drawColor(color);
        v.draw(c);
        return b;
    }

    /**
     * 从文件读取方式一：获取缩放后的本地图片【不建议使用，效率低】
     *
     * @param filePath 文件路径
     * @param width    宽
     * @param height   高
     * @return
     */
    public static Bitmap readBitmapFromFile(String filePath, int width, int height) {
        if (TextUtils.isEmpty(filePath)) return null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        float srcWidth = options.outWidth;
        float srcHeight = options.outHeight;
        int inSampleSize = 1;

        if (srcHeight > height || srcWidth > width) {
            if (srcWidth > srcHeight) {
                inSampleSize = Math.round(srcHeight / height);
            } else {
                inSampleSize = Math.round(srcWidth / width);
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeFile(filePath, options);
    }

    /**
     * 从文件读取方式二
     *
     * @param filePath
     * @return
     */
    public static Bitmap readBitmapFromFileDescriptor(String filePath) {
        try {
            FileInputStream fis = new FileInputStream(filePath);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 从文件读取方式二：获取缩放后的本地图片【建议使用，效率高，相对于方式一效率提升3倍】
     *
     * @param filePath 文件路径
     * @param width    宽
     * @param height   高
     * @return
     */
    public static Bitmap readBitmapFromFileDescriptor(String filePath, int width, int height) {
        try {
            FileInputStream fis = new FileInputStream(filePath);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options);
            float srcWidth = options.outWidth;
            float srcHeight = options.outHeight;
            int inSampleSize = 1;
            if (srcHeight > height || srcWidth > width) {
                if (srcWidth > srcHeight) {
                    inSampleSize = Math.round(srcHeight / height);
                } else {
                    inSampleSize = Math.round(srcWidth / width);
                }
            }

            if (inSampleSize > 2) {
                inSampleSize = 2;
            }

            options.inJustDecodeBounds = false;
            options.inSampleSize = inSampleSize;
            return BitmapFactory.decodeFileDescriptor(fis.getFD(), null, options);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 从文件读取方式三
     *
     * @param filePath
     * @return
     */
    public static Drawable readBitmapFromFileDrawable(String filePath) {
        Drawable drawable = Drawable.createFromPath(filePath);
        return drawable;
    }

    /**
     * 从输入流中读取文件：获取缩放后的本地图片
     *
     * @param ins    输入流
     * @param width  宽
     * @param height 高
     * @return
     */
    public static Bitmap readBitmapFromInputStream(InputStream ins, int width, int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(ins, null, options);
        float srcWidth = options.outWidth;
        float srcHeight = options.outHeight;
        int inSampleSize = 1;

        if (srcHeight > height || srcWidth > width) {
            if (srcWidth > srcHeight) {
                inSampleSize = Math.round(srcHeight / height);
            } else {
                inSampleSize = Math.round(srcWidth / width);
            }
        }

        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;

        return BitmapFactory.decodeStream(ins, null, options);
    }

    /**
     * 从资源文件中读取文件：获取缩放后的本地图片
     *
     * @param resources：资源对象
     * @param resourcesId：资源id
     * @param width：宽
     * @param height：高
     * @return
     */
    public static Bitmap readBitmapFromResource(Resources resources, int resourcesId, int width, int height) {
        InputStream ins = resources.openRawResource(resourcesId);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(ins, null, options);
        float srcWidth = options.outWidth;
        float srcHeight = options.outHeight;
        int inSampleSize = 1;

        if (srcHeight > height || srcWidth > width) {
            if (srcWidth > srcHeight) {
                inSampleSize = Math.round(srcHeight / height);
            } else {
                inSampleSize = Math.round(srcWidth / width);
            }
        }

        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;

        return BitmapFactory.decodeResource(resources, resourcesId, options);
    }

    /**
     * 图片转二进制
     *
     * @param bm：要做转换的图片
     * @return
     */
    public static byte[] bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    /**
     * 图片转二进制
     *
     * @param drawable：要做转换的图片
     * @return
     */
    public static byte[] drawable2Bytes(Drawable drawable) {
        if (drawable == null) return null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Bitmap bm = drawableToBitmap(drawable);
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    /**
     * 从二进制数据读取图片：获取缩放后的本地图片
     *
     * @param data
     * @param width
     * @param height
     * @return
     */
    public static Bitmap readBitmapFromByteArray(byte[] data, int width, int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, 0, data.length, options);
        float srcWidth = options.outWidth;
        float srcHeight = options.outHeight;
        int inSampleSize = 1;

        if (srcHeight > height || srcWidth > width) {
            if (srcWidth > srcHeight) {
                inSampleSize = Math.round(srcHeight / height);
            } else {
                inSampleSize = Math.round(srcWidth / width);
            }
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        return BitmapFactory.decodeByteArray(data, 0, data.length, options);
    }

    /**
     * 从assets文件读取图片：获取缩放后的本地图片
     *
     * @param context  上下文对象
     * @param filePath 文件路径
     * @return
     */
    public static Bitmap readBitmapFromAssetsFile(Context context, String filePath) {
        Bitmap image = null;
        InputStream is = null;
        try {
            AssetManager am = context.getResources().getAssets();
            is = am.open(filePath);
            image = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return image;
    }

    /**
     * 得到bitmap的大小
     */
    public static int getBitmapSize(Bitmap bitmap) {
        if (bitmap == null) return 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    //API 19
            return bitmap.getAllocationByteCount() / 1024 / 1024;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {//API 12
            return bitmap.getByteCount() / 1024 / 1024;
        }
        // 在低版本中用一行的字节x高度
        return bitmap.getRowBytes() * bitmap.getHeight() / 1024 / 1024;                //earlier version
    }

    /**
     * 图片保存文件
     *
     * @param filePath
     * @param b
     * @param quality
     */
    public static void writeBitmapToFile(String filePath, Bitmap b, int quality) {
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            File desFile = new File(filePath);
            fos = new FileOutputStream(desFile);
            bos = new BufferedOutputStream(fos);
            b.compress(Bitmap.CompressFormat.JPEG, quality, bos);
            bos.flush();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.flush();
                    bos.close();
                } catch (Exception e) {
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (Exception e) {
                }
            }
        }
    }

    /**
     * bitmap写入到文件。
     * <p>该方法适用于写入小文件，因为这是一次性的</p>
     *
     * @param file  文件实例
     * @param image 写入图片
     * @param file  文件实例
     * @return file存在则删除，写入新的内容
     */
    public static void saveBitmap(Bitmap image, File file, boolean isCompressBit) {
        if (file.exists()) {
            file.delete();
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            if (isCompressBit) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                if (baos.toByteArray().length > FileDialDefinedUtil.IMAGE_SIZE * 2) {//图片小于50，不进行压缩。
                    int options = 100;
                    while (baos.toByteArray().length / 1024 > FileDialDefinedUtil.IMAGE_SIZE) { //图片很大，质量最低压倒40%。
                        baos.reset();//重置baos即清空baos
                        image.compress(Bitmap.CompressFormat.JPEG, options, baos);
                        options -= 10;
                    }
                }
                ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
                Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
                if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
                    out.flush();
                    out.close();
                }
            } else {
                if (image.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
                    out.flush();
                    out.close();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 图片压缩
     *
     * @param image：要压缩的图片
     * @return
     */
    private static Bitmap compressImage(Bitmap image) {
        if (image == null) {
            return null;
        }
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            byte[] bytes = baos.toByteArray();
            ByteArrayInputStream isBm = new ByteArrayInputStream(bytes);
            Bitmap bitmap = BitmapFactory.decodeStream(isBm);
            return bitmap;
        } catch (Error e) {
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }

    /**
     * 图片缩放：根据scale生成一张图片
     *
     * @param bitmap
     * @param scale  等比缩放值
     * @return
     */
    public static Bitmap bitmapScale(Bitmap bitmap, float scale) {
        if (bitmap == null) return null;
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale); // 长和宽放大缩小的比例
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizeBmp;
    }

    /**
     * 获取图片旋转角度：读取照片exif信息中的旋转角度
     *
     * @param path 照片路径
     * @return角度
     */
    private static int readPictureDegree(String path) {
        if (TextUtils.isEmpty(path)) {
            return 0;
        }
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (Exception e) {
        }
        return degree;
    }

    /**
     * 图片旋转角度：获取图片旋转角度
     *
     * @param b:要旋转的图片
     * @param rotateDegree：要旋转的角度
     * @return
     */
    private static Bitmap rotateBitmap(Bitmap b, float rotateDegree) {
        if (b == null) {
            return null;
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(rotateDegree);
        Bitmap rotaBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
        return rotaBitmap;
    }

    /**
     * Drawable转Bitmap
     *
     * @param drawable：要转换的Drawable
     * @return
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) return null;
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;
    }

    public static Bitmap byteToBitmap(byte[] imgByte) {
        if (imgByte == null || imgByte.length == 0) return null;
        InputStream input = null;
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8;
        input = new ByteArrayInputStream(imgByte);
        SoftReference softRef = new SoftReference(BitmapFactory.decodeStream(
                input, null, options));
        bitmap = (Bitmap) softRef.get();
        if (imgByte != null) {
            imgByte = null;
        }

        try {
            if (input != null) {
                input.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bitmap;
    }

    /**
     * 转换为圆角图片
     *
     * @param source
     * @param radius
     * @return
     */
    public static Bitmap transform2CornerBitmap(Bitmap source, float radius) {
        if (source == null) {
            return null;
        }
        int x = source.getWidth();
        int y = source.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setAntiAlias(true);
        canvas.drawRoundRect(0, 0, x, y, radius, radius, paint);
        return bitmap;
    }

    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float corners) {
        try {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
            final Paint paint = new Paint();
            final Rect rect = new Rect(0, 0, bitmap.getWidth(),
                    bitmap.getHeight());
            final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(),
                    bitmap.getHeight()));
            paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(Color.BLACK);
            canvas.drawRoundRect(rectF, corners, corners, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            final Rect src = new Rect(0, 0, bitmap.getWidth(),
                    bitmap.getHeight());
            canvas.drawBitmap(bitmap, src, rect, paint);
            return output;
        } catch (Exception e) {
            return bitmap;
        }
    }

    /**
     * 将文件保存到公共的媒体文件夹
     * //这里的filepath不是绝对路径，而是某个媒体文件夹下的子路径，和沙盒子文件夹类似
     * //这里的filename单纯的指文件名，不包含路径
     *
     * @param fileName
     * @param bitmap
     */
    public static void saveSignImage(Context context,String fileName, Bitmap bitmap) {
        try {
            //设置保存参数到ContentValues中
            ContentValues contentValues = new ContentValues();
            //设置文件名
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
            //兼容Android Q和以下版本
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //android Q中不再使用DATA字段，而用RELATIVE_PATH代替
                //RELATIVE_PATH是相对路径不是绝对路径
                //DCIM是系统文件夹，关于系统文件夹可以到系统自带的文件管理器中查看，不可以写没存在的名字
                contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/");
                //contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Music/signImage");
            } else {
                contentValues.put(MediaStore.Images.Media.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
            }
            //设置文件类型
            contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG");
            //执行insert操作，向系统文件夹中添加文件
            //EXTERNAL_CONTENT_URI代表外部存储器，该值不变
            Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            if (uri != null) {
                //若生成了uri，则表示该文件添加成功
                //使用流将内容写入该uri中即可
                OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
                if (outputStream != null) {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
                    outputStream.flush();
                    outputStream.close();
                }
            }
        } catch (Exception e) {
        }
    }

    public static Bitmap view2Bitmap(final View view, int width, int height) {
        if (view == null) return null;
        Bitmap ret = Bitmap.createBitmap(width,
                height,
                Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(ret);
        Drawable bgDrawable = view.getBackground();
        if (bgDrawable != null) {
            bgDrawable.draw(canvas);
        } else {
            canvas.drawColor(Color.WHITE);
        }
        view.draw(canvas);
        return ret;
    }

    public static Bitmap view2BitmapBlackBg(final View view, int width, int height) {
        if (view == null) return null;
        Bitmap ret = Bitmap.createBitmap(width,
                height,
                Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(ret);
        canvas.drawColor(Color.BLACK);
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        view.draw(canvas);
        return ret;
    }

    public static Bitmap view2BitmapWithAlpha(final View view, int width, int height) {
        if (view == null) return null;
        Bitmap ret = Bitmap.createBitmap(width,
                height,
                Bitmap.Config.ARGB_8888);
        ret.eraseColor(Color.argb(0, 0, 0, 0));
        Canvas canvas = new Canvas(ret);
        canvas.drawColor(Color.TRANSPARENT);
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        view.draw(canvas);
        return ret;
    }

    public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) {
        // 获得图片的宽高
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        return newbm;
    }

    public static Bitmap scaleDrawable(Drawable drawable, int w, int h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        Bitmap newbmp = Bitmap.createScaledBitmap(bitmap, w, h, true);
        return newbmp;
    }

    public static Bitmap view2Bitmap(final View view) {
        if (view == null) return null;
        Bitmap ret = Bitmap.createBitmap(view.getWidth(),
                view.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(ret);
        Drawable bgDrawable = view.getBackground();
        if (bgDrawable != null) {
            bgDrawable.draw(canvas);
        } else {
            canvas.drawColor(Color.WHITE);
        }
        view.draw(canvas);
        return ret;
    }

    /**
     * 将圆图转换为方图
     *
     * @param source
     * @return
     */
    public static Bitmap formatCircle2Rectangle(Bitmap source) {
        if (source == null) {
            return null;
        }
        Bitmap bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        BitmapShader bitmapShader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        Paint paint = new Paint();
        paint.setShader(bitmapShader);
        canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
        return bitmap;
    }

    public static Drawable bitmap2Drawable(final Bitmap bitmap, Context context) {
        return bitmap == null ? null : new BitmapDrawable(context.getResources(), bitmap);
    }


    public static void drawableToFile(Drawable drawable, String filePath, Bitmap.CompressFormat format) {
        if (drawable == null)
            return;

        try {
            File file = new File(filePath);

            if (file.exists())
                file.delete();

            if (!file.exists())
                file.createNewFile();

            FileOutputStream out = null;
            out = new FileOutputStream(file);
            ((BitmapDrawable) drawable).getBitmap().compress(format, 100, out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Bitmap makeTintBitmap(Bitmap inputBitmap, int tintColor) {
        if (inputBitmap == null) {
            return null;
        }

        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap.getWidth(), inputBitmap.getHeight(), inputBitmap.getConfig());
        Canvas canvas = new Canvas(outputBitmap);
        Paint paint = new Paint();
        paint.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(inputBitmap, 0, 0, paint);
        return outputBitmap;
    }

    public static Bitmap mergeBitmap(Bitmap firstBitmap, Bitmap secondBitmap) {
        Bitmap bitmap = Bitmap.createBitmap(firstBitmap.getWidth(), firstBitmap.getHeight(), firstBitmap.getConfig());
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(firstBitmap, new Matrix(), null);
        canvas.drawBitmap(secondBitmap, 0, 0, null);
        return bitmap;
    }

    public static Bitmap mergeBitmapGroup(ArrayList<Bitmap> bitmaps, ArrayList<String> tintColors) {
        if (bitmaps == null) {
            return null;
        }
        Bitmap bitmap = Bitmap.createBitmap(bitmaps.get(0).getWidth(), bitmaps.get(0).getHeight(), bitmaps.get(0).getConfig());
        Canvas canvas = new Canvas(bitmap);
        for (int i = 0; i < bitmaps.size(); i++) {
            Paint paint = new Paint();

            if (!TextUtils.isEmpty(tintColors.get(i))) {
                paint.setColorFilter(new PorterDuffColorFilter(Color.parseColor(tintColors.get(i)), PorterDuff.Mode.SRC_IN));
            }
            if (i == 0) {
                canvas.drawBitmap(bitmaps.get(i), new Matrix(), paint);
                canvas.setDrawFilter(new DrawFilter());
            } else {
                canvas.drawBitmap(bitmaps.get(i), 0, 0, paint);
            }
        }
        return bitmap;
    }

}
